# -*- coding: utf-8 -*-
# @Time    : 2024/7/24 15:02
# @Author  : yujiahao
# @File    : 59_fastapi_dependent.py
# @description:高级依赖项

#  todo 就是把类的实例作为依赖传递过去
# 参数化的依赖项

"""
参数化的依赖项
我们之前看到的所有依赖项都是写死的函数或类。

但也可以为依赖项设置参数，避免声明多个不同的函数或类。

假设要创建校验查询参数 q 是否包含固定内容的依赖项。

但此处要把待检验的固定内容定义为参数。
"""

# 可调用实例
# Python 可以把类实例变为可调用项。
# 这里说的不是类本身（类本就是可调用项），而是类实例。
# 为此，需要声明 __call__ 方法：
from fastapi import Depends, FastAPI

app = FastAPI()


# 定义一个检查固定内容的类
class FixedContentQueryChecker:

    # 参数化实例 声明用于参数化依赖项的实例参数
    def __init__(self, fixed_content: str):
        # 初始化方法，接收一个固定内容的字符串
        self.fixed_content = fixed_content

    # FastAPI 使用 __call__ 检查附加参数及子依赖项，稍后，还要调用它向路径操作函数传递值。
    # __call__ 方法和 Scala 中的 apply 方法很相似，都提供了一种语法糖，可以省略显示的方法调用，使得类的实例向函数一样被调用。
    def __call__(self, q: str = ""):
        # 定义类实例被调用时的行为
        # 接收一个查询参数 q，默认为空字符串
        if q:
            # 如果查询参数 q 存在，检查固定内容是否在查询参数中
            return self.fixed_content in q
        # 如果查询参数 q 不存在，返回 False
        return False


# 创建 FixedContentQueryChecker 类的实例，并传入固定内容 "bar"
# 这样就可以参数化依赖项，它包含 checker.fixed_content 的属性 - "bar"。
checker = FixedContentQueryChecker("bar")


# 定义一个路径操作函数，用于处理 GET 请求
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: bool = Depends(checker)):
    # 把实例作为依赖项
    # 使用 Depends 声明依赖项 fixed_content_included，其值由 checker 提供
    # 返回一个字典，表示查询参数中是否包含固定内容
    return {"fixed_content_in_query": fixed_content_included}
